package org.jeecg.modules.rental.util;

import org.jeecg.modules.rental.vo.Circle;
import org.jeecg.modules.rental.vo.LocationPoint;
import org.jeecg.modules.rental.vo.Polygon;

import java.util.List;

import static java.lang.Math.*;

public class FenceUtils {


    public static boolean isPointInPolygon(LocationPoint point, Polygon polygon) {
        double x = point.longitude;
        double y = point.latitude;
        int crossings = 0;
        List<LocationPoint> vertices = polygon.vertices;
        int n = vertices.size();

        for (int i = 0; i < n; i++) {
            LocationPoint p1 = vertices.get(i);
            LocationPoint p2 = vertices.get((i + 1) % n);

            // 保证 p1.y < p2.y
            if (p1.latitude > p2.latitude) {
                LocationPoint temp = p1;
                p1 = p2;
                p2 = temp;
            }

            // 1. 点的y坐标不在边y坐标范围内，则不相交
            if(y < p1.latitude || y >= p2.latitude){
                continue;
            }

            // 2. 如果边是水平的
            if (p1.latitude == p2.latitude) {
                continue;
            }


            double x_cross = (y - p1.latitude) * (p2.longitude - p1.longitude) / (p2.latitude - p1.latitude) + p1.longitude;

            if (x > x_cross) {
                crossings++;
            }
        }

        return crossings % 2 != 0;
    }



    private static final double EARTH_RADIUS = 6371000; // 地球平均半径，单位为米

    /**
     * 计算地球上两点之间的距离（米）
     * @param p1 第一个点
     * @param p2 第二个点
     * @return 两点之间的距离，单位为米
     */
    public static double calculateDistance(LocationPoint p1, LocationPoint p2) {
        double lat1Rad = toRadians(p1.latitude);
        double lon1Rad = toRadians(p1.longitude);
        double lat2Rad = toRadians(p2.latitude);
        double lon2Rad = toRadians(p2.longitude);

        double dLon = lon2Rad - lon1Rad;
        double dLat = lat2Rad - lat1Rad;

        double a = pow(sin(dLat / 2), 2) + cos(lat1Rad) * cos(lat2Rad) * pow(sin(dLon / 2), 2);
        double c = 2 * asin(sqrt(a));
        return EARTH_RADIUS * c;
    }


    /**
     * 判断点是否在圆形围栏内
     * @param point 待判断的点
     * @param circle 圆形围栏
     * @return true 如果点在圆形围栏内或边界上，false 否则
     */
    public static boolean isPointInCircle(LocationPoint point, Circle circle) {
        double distance = calculateDistance(point, circle.center);
        return distance <= circle.radius;
    }
}
